﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace JewererBasic.Classes
{   
    public class Process_Report_Repository
    {
        public static Process_Report_View Generate_Report(string reporter)
        {
            Process_Report_View result = new Process_Report_View();
            result.Report_Time = DateTime.Now;
            result.Reporter = reporter;
            result.Processes = new List<Process_Step>();

            // get all unfinish bag_process_history
            MSQDBEntities dc = new MSQDBEntities();
            List<BAG_PROCESS_HISTORY> bag_process_histories = (from d in dc.BAG_PROCESS_HISTORY
                                                               where d.Status == 0
                                                               select d).OrderBy(m => m.IdProcess).ToList();
            if (bag_process_histories.Count > 0)
            {
                foreach (var bag_process_history in bag_process_histories)
                {
                    BAG bag = bag_process_history.BAG;
                    PROCESS process = bag_process_history.PROCESS;
                    ORDER_PRODUCT order_product = bag.ORDER_PRODUCT;
                    
                    // Get or Create process_step
                    Process_Step process_step = result.Processes.FirstOrDefault(m => m.Process_Id.Equals(process.Id));
                    if (process_step == null)
                    {
                        process_step = new Process_Step();
                        process_step.Process_Id = process.Id;
                        process_step.Process_Name = process.Name;

                        result.Processes.Add(process_step);
                    }                    

                    #region Get component data from database
                    if (bag.BAG_COMPONENT.Count > 0)
                    {
                        bool has_exported_bag = false;
                        foreach (var bag_component in bag.BAG_COMPONENT)
                        {
                            if (bag_component.Weight > 0)
                            {
                                if (process_step.Components == null)
                                    process_step.Components = new List<Component_Stone_Process_report>();
                                has_exported_bag = true;

                                // Get or create component                        
                                Component_Stone_Process_report tem_component = process_step.Components.FirstOrDefault(m => m.Id.Equals(bag_component.IdComponent));
                                if (tem_component == null)
                                {
                                    tem_component = new Component_Stone_Process_report();
                                    tem_component.Id = bag_component.IdComponent;
                                    tem_component.Orders = new List<Order_Process_Report>();

                                    process_step.Components.Add(tem_component);
                                }

                                // Get or create Order
                                Order_Process_Report tem_order = tem_component.Orders.FirstOrDefault(m => m.Order_Id == order_product.IdOrder);
                                if (tem_order == null)
                                {
                                    tem_order = new Order_Process_Report();
                                    tem_order.Order_Id = order_product.IdOrder;
                                    tem_order.Products = new List<Product_Process_Report>();

                                    tem_component.Orders.Add(tem_order);
                                }
                                tem_order.Total_Bag += 1;

                                // Get or create Product
                                Product_Process_Report tem_product = tem_order.Products.FirstOrDefault(m => m.Product_Name.Equals(order_product.IdProduct));
                                if (tem_product == null)
                                {
                                    tem_product = new Product_Process_Report();
                                    tem_product.Product_Name = order_product.IdProduct;
                                    tem_product.Bags = new List<Bag_Process_Report>();

                                    tem_order.Products.Add(tem_product);
                                }

                                // Create Bag
                                Bag_Process_Report tem_bag = new Bag_Process_Report();
                                tem_bag.Bag_Id = bag.Id;
                                tem_bag.Finish_Week = bag.Finish;
                                tem_bag.Product_Qty = bag.Number;
                                tem_bag.Component_Weight = bag_component.Weight;

                                tem_product.Bags.Add(tem_bag);
                                tem_product.Product_Qty += tem_bag.Product_Qty;

                                tem_component.Total_Weight += tem_bag.Component_Weight;
                            }
                        }
                        if (has_exported_bag)
                        {
                            process_step.Total_Bag_Component += 1;
                        }
                    }
                    #endregion

                    #region Get stone data from database
                    if (bag.BAG_STONE.Count > 0)
                    {
                        bool has_exported_bag = false;
                        foreach (var bag_stone in bag.BAG_STONE)
                        {
                            if (bag_stone.Weight > 0)
                            {
                                has_exported_bag = true;
                                if (process_step.Stones == null)
                                    process_step.Stones = new List<Component_Stone_Process_report>();

                                // Get or create Stone
                                Component_Stone_Process_report tem_stone = process_step.Stones.FirstOrDefault(m => m.Id.Equals(bag_stone.IdStone));
                                if (tem_stone == null)
                                {
                                    tem_stone = new Component_Stone_Process_report();
                                    tem_stone.Id = bag_stone.IdStone;
                                    tem_stone.Orders = new List<Order_Process_Report>();

                                    process_step.Stones.Add(tem_stone);
                                }

                                // Get or create Order
                                Order_Process_Report tem_order = tem_stone.Orders.FirstOrDefault(m => m.Order_Id == order_product.IdOrder);
                                if (tem_order == null)
                                {
                                    tem_order = new Order_Process_Report();
                                    tem_order.Order_Id = order_product.IdOrder;
                                    tem_order.Products = new List<Product_Process_Report>();

                                    tem_stone.Orders.Add(tem_order);
                                }
                                tem_order.Total_Bag += 1;

                                // Get or create Product
                                Product_Process_Report tem_product = tem_order.Products.FirstOrDefault(m => m.Product_Name.Equals(order_product.IdProduct));
                                if (tem_product == null)
                                {
                                    tem_product = new Product_Process_Report();
                                    tem_product.Product_Name = order_product.IdProduct;
                                    tem_product.Bags = new List<Bag_Process_Report>();

                                    tem_order.Products.Add(tem_product);
                                }

                                // Create Bag
                                Bag_Process_Report tem_bag = new Bag_Process_Report();
                                tem_bag.Bag_Id = bag.Id;
                                tem_bag.Finish_Week = bag.Finish;
                                tem_bag.Product_Qty = bag.Number;
                                tem_bag.Stone_Qty = bag_stone.Numb;
                                tem_bag.Stone_Weight = bag_stone.Weight;

                                tem_product.Bags.Add(tem_bag);
                                tem_product.Product_Qty += tem_bag.Product_Qty;

                                tem_stone.Total_Qty += bag_stone.Numb;
                                tem_stone.Total_Weight += bag_stone.Weight;
                            }
                        }
                        if (has_exported_bag)
                        {
                            process_step.Total_Bag_Stone += 1;
                        }
                    }
                    #endregion                    

                    if (process_step.Total_Bag_Stone+process_step.Total_Bag_Component==0)
                    {
                        result.Processes.Remove(process_step);
                    }

                }
                result.Total_Bag_Component = result.Processes.Sum(m => m.Total_Bag_Component);
                result.Total_Bag_Stone = result.Processes.Sum(m => m.Total_Bag_Stone);
                return result;
            }
            else
            {
                ErrorLog.Instance.InternalErrors.Add("There are no started BAG!");
                return null;
            }
        }
    }          

    public class Process_Report_View
    {
        public List<Process_Step> Processes { get; set; }

        public DateTime Report_Time { get; set; }

        public string Reporter { get; set; }

        public int Total_Bag_Component { get; set; }

        public int Total_Bag_Stone { get; set; }
    }    

    public class Process_Step
    {
        public int Process_Id { get; set; }

        public string Process_Name { get; set; }

        public int Total_Bag_Component { get; set; }

        public int Total_Bag_Stone { get; set; }

        public List<Component_Stone_Process_report> Stones { get; set; }

        public List<Component_Stone_Process_report> Components { get; set; }        
    }    

    public class Component_Stone_Process_report
    {               
        public string Id { get; set; }

        public double Total_Weight { get; set; }

        public int Total_Qty { get; set; }

        public List<Order_Process_Report> Orders { get; set; }
    }        

    public class Order_Process_Report
    {        
        public string Order_Id { get; set; }

        public int Total_Bag { get; set; }

        public List<Product_Process_Report> Products { get; set; }
    }

    public class Product_Process_Report
    {
        public string Product_Name { get; set; }

        public int Product_Qty { get; set; }

        public List<Bag_Process_Report> Bags { get; set; }
    }

    public class Bag_Process_Report
    {
        public string Bag_Id { get; set; }

        public int Product_Qty { get; set; }

        public int Finish_Week { get; set; }

        public double Component_Weight { get; set; }

        public int Stone_Qty { get; set; }

        public double Stone_Weight { get; set; }
    }
}